1. The use by human beings of voice sounds, and often written symbols representing these sounds, in organized combinations and patterns in order to express and communicate thoughts and feelings.
2. A system of symbols and rules used for communication with or between computers.
climax (kli’∑maks) n.
1. The point of greatest intensity or force in an ascending series or progression; a culmination.
2. A moment of great or culminating intensity in a narrative or drama, especially the conclusion of a crisis.
3. See orgasm.
AppleScript is a wonderful tool. It's extensive and complex, but while it tries very hard to be user-friendly and be a “plain English” kind of language, it's not always that easy to get it to do the things you want. With that in mind, this guide has been designed as an introduction to some of the finer points of AppleScript, by way of fifty or so examples.
Who knows, even the most experienced user might learn something new by browsing this file. I know that I've learned a lot about AppleScript in the process of developing, working with, and (well, I have to admit it) playing with CLImax. Frankly, Apple just continues to impress me with the usefulness and flexibility of its system software. [Um, most of the time... we won't talk about the real inner workings of AppleScript. ;-) ]
Enough talking. Enjoy!
Navigating in the Finder
1 • open startup disk
2 • items of front window
3 • close front window
4 • items of startup disk
5 • close windows -- or "close every window"
These first five commands serve as a basic intro on how to navigate the Finder via AppleScript. First off, when you tell the Finder to open something, it does. (Assuming, that is, it can figure out what you're asking it to open.) Just like that. It's terrifically easy.
[n.b.: This file assumes that you've got CLImax up and running by now, and are trying out these commands as you read. If you're not, then do it! :-) I didn't make it a magic floating window for nothing. In fact, try turning on mouse focus, and copying and pasting (or dragging and dropping) the examples from this file straight into CLImax.
Hold down the command key to replace the window’s entire contents when using drag-and-drop. ]
When you execute a command such as “items of front window”, the Finder builds a list of the items in the front window (which in this case should belong to the startup disk which you just opened) and returns that list as the result. CLImax then tells AppleScript to convert that list to human-readable text, and displays it in the right half of its window. Notice that files and folders are returned in the form “file x of folder y of folder z of disk w”. It makes for very verbose output, but the biggest benefit of doing it this way is that portions of a result can be copied and pasted into the script window for use in another command.
The third command closes the front window, just as you'd expect. The fourth command is to show that you don't need to have a window open or be able to see a file in order to do something with it, or to get a list of the files in a folder.
6 • open disk "Macintosh HD"
7 • open folder "Macintosh HD:System Folder"
8 • open system folder
9 • open folder "Extensions" of front window
10 • open folder 3 of window 2
11 • open the fourth folder in the 1st window
Now we're getting a little more complicated. Let's look at what each of these does. Number six is to show that you can refer to disks by name, which isn't that hard to guess. Seven refers to the system folder on that disk by using a full pathname. (Notice that AppleScript still returns the parent-container form as the result.)
The eighth command is a little more interesting. The Finder has a short list of special folders that you can refer to by name, without quotation marks. These include: control panels folder, preferences folder, startup items folder, extensions folder, apple menu items folder, and so on. So rather than typing: folder “System Folder” of disk “Macintosh HD”, or: folder “Macintosh HD:System Folder”, you can shortcut directly to it with: system folder. This can be useful for folders such as the Preferences and Extensions folders that you may need to open often, but don't have a shortcut to.
Nine gives you an idea of how to use the visual information (the front window) in conjunction with CLImax in order to navigate. There are easier ways of doing this without CLImax (for example, you can simply type the name of an item in the Finder to select it), but as always with the Macintosh experience, there's more than one way to do it.
Number ten is a demonstration that every item in a container has a numeric index. This isn't necessarily all that useful in itself, because while the index usually makes sense in the Finder (alphabetical order for name and icon views, sorted order for sorted list views, and front-to-back order for windows, just to name a few examples) it's not the sort of thing you can always rely upon, because in general humans don't think in numbers, and not everything is indexed the way you'd expect. (Like processes.) If you need to sort a list of records, AppleScript has its own comparison and sorting operators that are much more useful. But the numeric indexes have their uses too, as we'll see later.
The last example in this set just goes to show that AppleScript is flexible enough to allow several different ways of referring to the numeric index. “The fourth folder” means the same thing as “folder 4”, and “front window” means the same as “the 1st window”, which means (you guessed it) "window 1". [You can also see from this example that AppleScript doesn't mind extraneous articles such as "the", as long as they make sense within its grammar.]
12 • folders in the system folder whose name contains "e"
13 • items of apple menu items folder whose kind is "alias"
14 • select files in the front window whose name ends with ".c"
15 • open files of folder "Downloads" whose file type is "APPL"
Now we're getting into some interesting territory!! The “whose” clause is one of the most powerful constructs AppleScript has to offer. Essentially, these examples do exactly what it looks like they do.
Hopefully you're starting to get ideas about ways that this could be useful now! Notice in #15 that you can refer to a file's type and creator via AppleScript, as well as its size, label, and many other properties. I strongly suggest that you browse through the Finder's dictionary, using your favorite script editor, and take a look at just how rich it really is. (Actually, CLImax can open it for you!! Tell it: dictionary for "Finder" . )
16 • put away disks whose local volume = false
17 • put away every disk whose ejectable is true -- or, "every disk where it isn't ejectable"
18 • close windows whose index > 2 -- or "whose index is greater than 2"
19 • files of extensions folder whose file type is "shlb" and name contains "Lib"
More examples of the “whose” clause at work!
The first example in this group does something that I find immensely useful. I work on a large network, and in the course of my everyday duties I sometimes end up with twenty or more remote file servers mounted. Picking them out one at a time from the midst of a cluttered desktop in order to dismount them isn't always easy. But with one command (which can be shortened, as we'll see later) I can get the Finder to go through and do it for me, much faster than I'd be able to do it myself. And sometimes, well, I get a kick out of seeing a computer actually make my life easier for once. :-)
The second example in this set removes all ejectable media (not hard disks, but actual ejectable media) from the desktop, using a different syntax, but one that’s equivalent to that of the first example. And the third example closes all windows but the front two, which is an excellent demonstration of the usefulness of the index number.
The fourth example is a demonstration of how to concatenate “whose” clauses. (Notice that I used “files” and not “items” in this example; this is because usually the extensions folder contains one or more folders, and folders do not have “file type” as a property. See the section on “Properties” below, and the file “AppleScript troubleshooting” for more information.)
20 • set view of front window to small icon
21 • set view of front window to size
22 • set icon size of item "views" of control panels folder to 0 -- or 1, or 2
23 • reveal file "control panels" of apple menu items folder
24 • reveal original item of selection
These are more examples of the power of the Finder's dictionary. Experienced AppleScript users will have seen these already, but CLImax brings a whole new meaning to a lot of these commands, since they're executed as soon as you finish typing them. (As opposed to: launching a script editor, and then going through the process of editing, compiling, and running a tiny applet, and then quiting the script editor if you're finished with it.)
Example 22 demonstrates the scriptability of the “Views” control panel, which is part of the Finder's dictionary. Unfortunately this is the only (standard) control panel with such support, because the control panel has to be either an application in its own right, or the capability has to be explicitly written into the Finder Scripting Extension. But at least the Views control panel has a relatively well-fleshed-out dictionary of commands…
The last two in this set demonstrate the “reveal” command, which opens the enclosing folder of its argument. In the last example, you also see the use of the “original item” property of alias files.
All of these are just simple examples, to show off some of the tricks that AppleScript and CLImax can make the Finder do. (Unfortunately, there isn't a “roll over” command yet. But I understand that the Copland engineers are working on it.) All of the commands I've given here are in a sense just primitives; AppleScript (working through and supplemented by CLImax) allows you to combine these in all sorts of ways in order to, well, actually get things done. Quickly and easily. If you're running CLImax and you ever find yourself doing something boring and repetitive, well, you're probably doing something wrong. :-) CLImax is designed as a tool to help you use AppleScript, which itself is a tool to simplify and automate complex tasks. Use it! It's worth it.
Okay, just one more before we move on to what AppleScript itself can do:
25 • sort (files of desktop & files of startup disk) by size
The Finder's sort command is slick, because you can sort any list of Finder objects, according to any of their properties! And it doesn't have to affect the view of the windows (in fact, the items don't even all have to be in the same location) so, because you're doing it with a command line rather than visually, you don't have to change the views back when you're done.
So! That's an introduction to the Finder's dictionary, and some of the things CLImax can do. There's much more; I've just skimmed the surface and shown you some of the cooler tricks. Like I said, I strongly suggest you look through the Finder's dictionary yourself, and look at other examples, and consider how to make it work for you. Even experienced users can do this again, to consider the ways in which being able to execute a string of single-line commands affects the “scripting experience”. :-)
However, making more complicated constructs can be difficult if you don't know some of the basics about how AppleScript works and what it expects. (Sometimes you can guess, but it's not always that easy.) Conveniently enough, though, that's what the next section is about. Some of it is brushed over fairly quickly, which is less than it deserves, because AppleScript is a very complex language. Remember, I'm not here to make you into an AppleScript expert. On the other hand, if you play around with CLImax enough, you might just do that yourself. :-)
A little bit of AppleScript syntax and grammar
Referring to lists of items
26 • {"a","b"} & {"b","c"}
27 • item 2 of { "Mac", "intosh" }
28 • items 2 thru 4 of { "1", "2", "3", "4" }
29 • open { startup disk, system folder, item "trash" of desktop }
A list in AppleScript consists of zero, one, or more items. That's it; that's all there is to it. Most commands in the Finder return a list of items as their result. To explicitly specify a list in a script, you can use curly braces, with list items separated by commas. When AppleScript returns a list of items, it's always in this brace-and-comma form.
You can join lists with the ampersand (&) operator, and you can also refer to items by their position in the list. Notice that the result of #27 is "intosh", which is not surrounded by curly braces because it's a single item and not a list, while #28 returns a list of three items, so that result is surrounded by curly braces.
Math
30 • 2 + 2
31 • 6 * 9
32 • 2^(6+5*8-(6*7-1))+10
33 • 3 ≠ 5 -- option-= generates ≠ character.
I think these examples pretty much speak for themselves. Yes, CLImax works as a calculator, too! :-) Standard arithmetic expressions, operators, and precedences apply. I can't take the credit, since it's actually AppleScript, but it's still pretty cool.
Things to know about variables
34 • set x to 2
35 • set y to system folder
36 • open item x of y
37 • set se to process "Script Editor"'s file as alias
38 • open result
If AppleScript encounters something that isn't a command, class, or other reserved word, it assumes that it's a variable name. When you define a variable, it gets saved in the script context so that you can refer to it later. Don't be fooled if it looks like I'm glossing over this, because it's actually one of the most useful things that CLImax does!
CLImax saves its script context, which is where variables and other types of global information are stored, in its preferences file. This means that it persists, well, forever! Or at least until you reset it. What this means is that you can quit and re-launch CLImax (in fact, try it now! option-tab, then tell it to “relaunch”), and the variables you've defined stick around! One simple use for this: it's a great way to get to commonly-used folders and files without having aliases lying around cluttering up your desktop or Apple menu. Just define a variable to point to an application you use often or a deeply-buried folder, and then use CLImax to tell the Finder to open it when you need it.
There's also a special variable (inherent to AppleScript) called “result”. You can use it to refer to the result of the last expression that was evaluated successfully. Since most things return sensible results, and they’re easily visible in CLImax’s window, you can use it as shorthand to string commands together. (“disks”, followed by “open result”).
Just in case you were wondering, variables aren't case-sensitive.
Properties, and ways to refer to them
39a • size of system folder
39b • size of extensions folder's container
40a • scriptable of process "CLImax"
40b • process "CLImax" is scriptable
41 • size of process "CLImax"'s file
42 • set visible of processes to false -- hides all applications but the Finder!
Everything that exists in AppleScript has some sort of class associated with it; examples are text, number, file, process, disk, container, and so on and so forth. A class defines (among other things) the properties of that item which can be referenced. The above are all examples of different ways to reference properties: you can say “property of item”, “item's property”, or in some cases “item is [or isn't] property”. (The last case is actually a kind of question, to which AppleScript answers either true or false.)
In complex applications such as the Finder, an object can belong to a hierarchy of classes. For example, item "control panels" of apple menu items folder refers to an object that is, simultaneously, an alias file, a file, and an item, and as a result it has all the properties of each of these classes. Try it!
43 • set x to item "control panels" of apple menu items folder
44 • original item of x -- one of the properties of an alias file
45 • creator type of x -- one of the properties of a file
46 • open information window of x -- one of the properties of an item
47 • entire contents of original item of x -- the original item is a folder, which is also a
-- container, which has the property "entire contents"
(Side note: In 7.5.1, there's a bug in the Finder which causes it to bring itself to the front whenever it handles the “original item” property. You may have noticed this yourself. :-)
Functions and References, for when a variable just isn't good enough
48 • set fw to ref front window
49 • set finder to ref application "Finder"
50 • on servers()
tell app "Finder"
return (disks whose local volume is false)
end tell
end servers
51 • on frontapp()
tell app "Finder"
set x to processes whose frontmost is true
if (x is {}) then set x to application "Finder"
return x
end
end
52 • on cfiles()
tell app "Finder" to return (files of front window whose name ends with ".c")
end
53 • on textfiles()
tell finder to return (files of fw whose file type is "TEXT")
end
54 • on ctc(t,c)
tell finder to set file type of selection to t
tell finder to set creator type of selection to c
end
54 • cfiles -- result: «handler cfiles»
55 • cfiles() -- result: { file "main.c" of folder "project folder", file "misc.c" of ...
56 • set creator type of textfiles() to "CWIE"
There are some things that you can't, or don't want to, set a variable for, because they're going to change. (If you try “set fw to front window”, then the variable fw gets attached to whatever window is frontmost at the time, which is probably not what you wanted!) Thus, we have functions and references!
A function is a special event handler that you can invoke by entering its name, followed by parentheses, with an optional set of parameters. You can think of a reference as a special type of variable, one that gets freshly resolved each time it's encountered.
For functions, the basic syntax is: on functionname( param1, param2, ... ), followed by the body of the function, followed by end functionname. The "ctc" function given above is probably the single handler I use most often in CLImax. :-) If you’re a programmer kind of person, you should be aware that variables used in handlers are local unless explicitly declared global.
For references, you can see the syntax above; instead of “set x to y”, use “set x to a reference to y” to create a reference, or the much less verbose shorthand “set x to ref y”. Be careful, though... you SHOULD NOT set a variable to an object reference containing a “whose” clause, as in the following:
set servers to ref disks whose local volume is false -- do NOT do this!!!
If you do, you'll end up corrupting your script context and CLImax will be unable to save it!! Use a function instead. (Read the file "Important Notes" for more information on this problem.)
Coercion, aka the casting couch
57 • 2^10 as text
58 • characters 1 thru 4 of result as text
59 • system folder as alias
60 • tell app "ResEdit" to open (finder's selection as alias) -- assuming finder = ref application "Finder"
61 • current application as hex dump -- when talking to CLImax (returns the PSN)
You can use “as” to tell AppleScript to coerce a given item to another format. Not everything can be coerced to everything else, and some things that seem as though they should be able to be coerced, can’t, but most of the time it does work. Usually it’s not explicitly necessary, but in example 60 above, ResEdit doesn't know how to interpret the object specifier that’s returned by “selection”, so you need to explicitly coerce it yourself.
CLImax has two special classes that most things can be coerced to, with varying degrees of success, for the purposes of Apple Event debugging. A "hex dump" is a byte listing of the data, and a "text dump" is a direct conversion of printable characters. The result is often interesting, as are the results of the info for and dump commands, but not always useful. :-)